/*
 * InstitutionTests.java
 *
 *  
 */
package org.msb.finance.data;

import static org.junit.Assert.*;

import java.util.Collection;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * 
 * 
 * @author boudream
 * 
 */
@SuppressWarnings("nls")
public class InstitutionTests {

	/*
	 * 
	 */
	private Institution institution;

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		this.institution = new Institution();
	}

	/**
	 * 
	 * @throws Exception
	 */
	@After
	public void tearDown() throws Exception {
		this.institution.delete();
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#hashCode()}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testHashCode() throws Exception {
		Institution i1 = this.institution;
		Institution i2 = new Institution();
		Institution i3 = new Institution();
		i3.setName("ADifferentName");

		assertEquals(this.institution.hashCode(), i1.hashCode());
		assertEquals(this.institution.hashCode(), i2.hashCode());
		assertFalse(this.institution.hashCode() == i3.hashCode());

		i1.delete();
		i2.delete();
		i3.delete();
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#Institution()}.
	 */
	@Test
	public void testInstitutionConstructor() {
		assertNotNull(this.institution);
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#setName(java.lang.String)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetName() throws Exception {
		final String NAME = "AnInstitution";

		this.institution.setName(NAME);
		assertEquals(NAME, this.institution.getName());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetNameWithNull() throws Exception {
		try {
			this.institution.setName(null);
			fail("Expected a NullPointerException to be thrown.");
		} catch (NullPointerException ex) {
			// Pass.
		}
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetNameToCurrentName() throws Exception {
		final String NAME = "AnInstitution";
		final String NAME2 = "AnInstitution";

		this.institution.setName(NAME);
		String name = this.institution.getName();

		try {
			this.institution.setName(NAME);
			assertSame(name, this.institution.getName());
		} catch (DuplicateNameException ex) {
			fail("Did not expect a DuplicateNameException to be thrown.");
		}

		try {
			this.institution.setName(NAME2);
			assertSame(name, this.institution.getName());
		} catch (DuplicateNameException ex) {
			fail("Did not expect a DuplicateNameException to be thrown.");
		}
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetNameTwice() throws Exception {
		final String NAME = "AnInstitution";
		final String NAME2 = "AnotherInstitution";

		this.institution.setName(NAME);
		this.institution.setName(NAME2);

		assertSame(NAME2, this.institution.getName());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetNameWithDuplicate() throws Exception {
		final String NAME = "AnInstitution";
		final String NAME2 = "AnInstitution";

		try {
			this.institution.setName(NAME);
		} catch (DuplicateNameException ex) {
			fail("Did not expect a DuplicateNameException to be thrown.");
		}

		try {
			Institution i1 = new Institution();
			i1.setName(NAME);
			fail("Expected a DuplicateNameException to be thrown.");
		} catch (DuplicateNameException ex) {
			// Pass.
		}

		try {
			Institution i2 = new Institution();
			i2.setName(NAME2);
			fail("Expected a DuplicateNameException to be thrown.");
		} catch (DuplicateNameException ex) {
			// Pass.
		}
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#setAddress(java.lang.String)}.
	 */
	@Test
	public void testSetAddress() {
		final String ADDRESS = "AnAddressForTheInstitution";
		final String ADDRESS2 = "ADifferentAddressForTheInstitution";

		this.institution.setAddress(ADDRESS);
		assertEquals(ADDRESS, this.institution.getAddress());

		this.institution.setAddress(ADDRESS2);
		assertEquals(ADDRESS2, this.institution.getAddress());
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#setPhone(java.lang.String)}.
	 */
	@Test
	public void testSetPhone() {
		final String PHONE = "212-555-5555";
		final String PHONE2 = "626-555-5555";

		this.institution.setPhone(PHONE);
		assertEquals(PHONE, this.institution.getPhone());

		this.institution.setPhone(PHONE2);
		assertEquals(PHONE2, this.institution.getPhone());
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#setFax(java.lang.String)}.
	 */
	@Test
	public void testSetFax() {
		final String FAX = "212-555-5001";
		final String FAX2 = "212-555-5002";

		this.institution.setFax(FAX);
		assertEquals(FAX, this.institution.getFax());

		this.institution.setFax(FAX2);
		assertEquals(FAX2, this.institution.getFax());
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#setWebsite(java.lang.String)}.
	 */
	@Test
	public void testSetWebsite() {
		final String WEBSITE = "www.institution.com";
		final String WEBSITE2 = "www.institution2.com";

		this.institution.setWebsite(WEBSITE);
		assertEquals(WEBSITE, this.institution.getWebsite());

		this.institution.setWebsite(WEBSITE2);
		assertEquals(WEBSITE2, this.institution.getWebsite());
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#setContactName(java.lang.String)}.
	 */
	@Test
	public void testSetContactName() {
		final String CONTACT = "JoeContact";
		final String CONTACT2 = "PhilContact";

		this.institution.setContactName(CONTACT);
		assertEquals(CONTACT, this.institution.getContactName());

		this.institution.setContactName(CONTACT2);
		assertEquals(CONTACT2, this.institution.getContactName());
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#setContactPhone(java.lang.String)}.
	 */
	@Test
	public void testSetContactPhone() {
		final String PHONE = "212-555-5555";
		final String PHONE2 = "626-555-5555";

		this.institution.setContactPhone(PHONE);
		assertEquals(PHONE, this.institution.getContactPhone());

		this.institution.setContactPhone(PHONE2);
		assertEquals(PHONE2, this.institution.getContactPhone());
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#setContactEmail(java.lang.String)}.
	 */
	@Test
	public void testSetContactEmail() {
		final String EMAIL = "joe.contact@institution.com";
		final String EMAIL2 = "phil.contact@institution.com";

		this.institution.setContactEmail(EMAIL);
		assertEquals(EMAIL, this.institution.getContactEmail());

		this.institution.setContactEmail(EMAIL2);
		assertEquals(EMAIL2, this.institution.getContactEmail());
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#setNotes(java.lang.String)}.
	 */
	@Test
	public void testSetNotes() {
		final String NOTES = "SomeNotes";
		final String NOTES2 = "SomeMoreNotes";

		this.institution.setNotes(NOTES);
		assertEquals(NOTES, this.institution.getNotes());

		this.institution.setNotes(NOTES2);
		assertEquals(NOTES2, this.institution.getNotes());
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#addAccount(org.msb.finance.data.Account)}.
	 */
	@Test
	public void testAddAccount() {
		Account account = new FakeAccount("Test Account");
		this.institution.addAccount(account);

		Collection<Account> accounts = this.institution.getAccounts();
		assertNotNull(accounts);
		assertEquals(1, accounts.size());
		assertTrue(accounts.contains(account));
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#removeAccount(org.msb.finance.data.Account)}.
	 */
	@Test
	public void testRemoveAccount() {
		Account account = new FakeAccount("AccountName");
		Account account2 = new FakeAccount("AccountName2");

		this.institution.addAccount(account);
		this.institution.addAccount(account2);

		this.institution.removeAccount(account);

		Collection<Account> accounts = this.institution.getAccounts();
		assertNotNull(accounts);
		assertEquals(1, accounts.size());
		assertFalse(accounts.contains(account));
		assertTrue(accounts.contains(account2));

		this.institution.removeAccount(account);

		accounts = this.institution.getAccounts();
		assertNotNull(accounts);
		assertEquals(1, accounts.size());
		assertFalse(accounts.contains(account));
		assertTrue(accounts.contains(account2));

		this.institution.removeAccount(account2);

		accounts = this.institution.getAccounts();
		assertNotNull(accounts);
		assertEquals(0, accounts.size());
		assertFalse(accounts.contains(account));
		assertFalse(accounts.contains(account2));
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#equals(java.lang.Object)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testEqualsObject() throws Exception {
		Institution i1 = this.institution;
		Institution i2 = new Institution();
		Institution i3 = new Institution();
		i3.setName("ADifferentName");

		assertTrue(this.institution.equals(i1));
		assertTrue(i1.equals(this.institution));

		assertTrue(this.institution.equals(i2));
		assertTrue(i2.equals(this.institution));

		assertTrue(i1.equals(i2));
		assertTrue(i2.equals(i1));

		assertFalse(this.institution.equals(i3));
		assertFalse(i3.equals(this.institution));

		assertFalse(this.institution.equals(new Object()));
		assertFalse(this.institution.equals(null));

		i1.delete();
		i2.delete();
		i3.delete();
	}

	/**
	 * Test method for {@link org.msb.finance.data.Institution#compareTo(org.msb.finance.data.Institution)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testCompareTo() throws Exception {
		this.institution.setName("InstitutionName");

		Institution i1 = new Institution();
		i1.setName("AAA-InstitutionName");

		Institution i2 = new Institution();
		i2.setName("ZZZ-InstitutionName");

		Institution i3 = new Institution();

		assertEquals(0, this.institution.compareTo(this.institution));
		assertTrue(0 < this.institution.compareTo(i1));
		assertTrue(0 > this.institution.compareTo(i2));
		assertEquals(0, i3.compareTo(i3));
		assertEquals(1, this.institution.compareTo(i3));
		assertEquals(-1, i3.compareTo(this.institution));
	}

	/*
	 * 
	 */
	class FakeAccount extends Account {

		/*
		 * 
		 */
		FakeAccount(String name) {
			super(name);
		}

	}
}
